package in.rinisoft.tools.sonar.maven.plugin;

import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactCollector;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.RuntimeInformation;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.batch.bootstrapper.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.bootstrapper.LoggingConfiguration;

import com.google.common.collect.Maps;

/**
 * Sonar Analysis Impl.
 *
 * @goal sonar-impl
 * @author Neeraj Mittal 
 *
 */
public class SonarMojo
    extends AbstractMojo
{
	  /**
	   * @parameter expression="${session}"
	   * @required
	   * @readonly
	   */
	  private MavenSession session;

	  /**
	   * @parameter expression="${project}"
	   * @required
	   * @readonly
	   */
	  private MavenProject project;

	  /**
	   * @component
	   * @required
	   */
	  private LifecycleExecutor lifecycleExecutor;

	  /**
	   * The artifact factory to use.
	   *
	   * @component
	   * @required
	   * @readonly
	   */
	  private ArtifactFactory artifactFactory;

	  /**
	   * The artifact repository to use.
	   *
	   * @parameter expression="${localRepository}"
	   * @required
	   * @readonly
	   */
	  private ArtifactRepository localRepository;
	  
	  
	  /**
	   * The artifact metadata source to use.
	   *
	   * @component
	   * @required
	   * @readonly
	   */	  
	  private ArtifactMetadataSource artifactMetadataSource;

	  /**
	   * The artifact collector to use.
	   *
	   * @component
	   * @required
	   * @readonly
	   */
	  private ArtifactCollector artifactCollector;
	  
	  
	  /**
	   * The dependency tree builder to use.
	   *
	   * @component
	   * @required
	   * @readonly
	   */
	  private DependencyTreeBuilder dependencyTreeBuilder;

	  /**
	   * @component
	   * @required
	   * @readonly
	   */
	  private MavenProjectBuilder projectBuilder;

	  /**
	   * @component
	   * @required
	   * @readonly
	   */
	  private RuntimeInformation runtimeInformation;

	  public void execute() throws MojoExecutionException, MojoFailureException {
	    ProjectDefinition def = MavenProjectConverter.convert(session.getProjects(), project);
	    ProjectReactor reactor = new ProjectReactor(def);

	    Batch batch = Batch.builder()
	      .setEnvironment(getEnvironmentInformation())
	      .setProjectReactor(reactor)
	      .addComponents(
	        session, getLog(), lifecycleExecutor, artifactFactory, localRepository, artifactMetadataSource, artifactCollector,
	        dependencyTreeBuilder, projectBuilder, PluginExecutor.class)
	      .build();

	    configureLogging(batch.getLoggingConfiguration());
	    batch.execute();
	  }

	  private void configureLogging(LoggingConfiguration logging) {
	    logging.setProperties(Maps.fromProperties(session.getSystemProperties()));
	    logging.setFormat(LoggingConfiguration.FORMAT_MAVEN);
	    if (getLog().isDebugEnabled()) {
	      logging.setVerbose(true);
	    }
	  }

	  private EnvironmentInformation getEnvironmentInformation() {
	    String mavenVersion = runtimeInformation.getApplicationVersion().toString();
	    return new EnvironmentInformation("Maven", mavenVersion);
	  }

}
